#include "coding.h"
#include "../util.h"


static const int step_table[4] = {
    5, 1, -1, -3
};

static const int mpc3_table[4][4][64] = {
    {
        {
            2,     2,     3,     7,     15,    27,    45,    70,    104,   148,   202,   268,   347,   441,   551,   677,  
            821,   984,   1168,  1374,  1602,  1854,  2131,  2435,  2767,  3127,  3517,  3938,  4392,  4880,  5402,  5960, 
            6555,  7189,  7862,  8577,  9333,  10132, 10976, 11865, 12802, 13786, 14819, 15903, 17038, 18226, 19469, 20766,
            22120, 23531, 25001, 26531, 28123, 29776, 31494, 33276, 35124, 37039, 39023, 41076, 43201, 45397, 47666, 50010
        },
        {
            1,     1,     2,     5,     10,    18,    31,    48,    72,    101,   139,   184,   239,   303,   378,   465,  
            564,   677,   803,   944,   1101,  1274,  1465,  1674,  1902,  2150,  2418,  2707,  3019,  3355,  3714,  4097, 
            4507,  4942,  5405,  5896,  6416,  6966,  7546,  8157,  8801,  9477,  10188, 10933, 11714, 12530, 13384, 14276,
            15207, 16177, 17188, 18240, 19334, 20471, 21652, 22877, 24148, 25464, 26828, 28240, 29700, 31210, 32770, 34382
        },
        {
            0,     0,     1,     2,     4,     8,     14,    22,    32,    46,    63,    83,    108,   138,   172,   211,  
            256,   307,   365,   429,   500,   579,   666,   761,   864,   977,   1099,  1230,  1372,  1525,  1688,  1862, 
            2048,  2246,  2457,  2680,  2916,  3166,  3430,  3708,  4000,  4308,  4631,  4969,  5324,  5695,  6084,  6489, 
            6912,  7353,  7813,  8291,  8788,  9305,  9841,  10398, 10976, 11574, 12194, 12836, 13500, 14186, 14895, 15628
        },
        {
            0,     0,     0,     0,     1,     3,     5,     8,     13,    18,    25,    33,    43,    55,    68,    84,   
            102,   123,   146,   171,   200,   231,   266,   304,   345,   390,   439,   492,   549,   610,   675,   745,  
            819,   898,   982,   1072,  1166,  1266,  1372,  1483,  1600,  1723,  1852,  1987,  2129,  2278,  2433,  2595, 
            2765,  2941,  3125,  3316,  3515,  3722,  3936,  4159,  4390,  4629,  4877,  5134,  5400,  5674,  5958,  6251
        },
    },
    {
        {
            1,     1,     2,     4,     9,     17,    28,    44,    65,    92,    126,   167,   217,   276,   344,   423,  
            513,   615,   730,   858,   1001,  1159,  1332,  1522,  1729,  1954,  2198,  2461,  2745,  3050,  3376,  3725, 
            4097,  4493,  4914,  5360,  5833,  6332,  6860,  7416,  8001,  8616,  9262,  9939,  10649, 11391, 12168, 12978,
            13825, 14707, 15626, 16582, 17576, 18610, 19683, 20797, 21952, 23149, 24389, 25673, 27000, 28373, 29791, 31256
        },
        {
            0,     0,     1,     2,     5,     10,    17,    26,    39,    55,    75,    100,   130,   165,   206,   254,  
            308,   369,   438,   515,   600,   695,   799,   913,   1037,  1172,  1319,  1477,  1647,  1830,  2025,  2235, 
            2458,  2696,  2948,  3216,  3499,  3799,  4116,  4449,  4800,  5169,  5557,  5963,  6389,  6835,  7300,  7787, 
            8295,  8824,  9375,  9949,  10546, 11166, 11810, 12478, 13171, 13889, 14633, 15403, 16200, 17023, 17874, 18753
        },
        {
            0,     0,     0,     1,     3,     6,     11,    17,    26,    37,    50,    67,    86,    110,   137,   169,  
            205,   246,   292,   343,   400,   463,   532,   608,   691,   781,   879,   984,   1098,  1220,  1350,  1490, 
            1638,  1797,  1965,  2144,  2333,  2533,  2744,  2966,  3200,  3446,  3704,  3975,  4259,  4556,  4867,  5191, 
            5530,  5882,  6250,  6632,  7030,  7444,  7873,  8319,  8781,  9259,  9755,  10269, 10800, 11349, 11916, 12502
        },
        {
            0,     0,     0,     0,     0,     1,     2,     4,     6,     9,     12,    16,    21,    27,    34,    42,   
            51,    61,    73,    85,    100,   115,   133,   152,   172,   195,   219,   246,   274,   305,   337,   372,  
            409,   449,   491,   536,   583,   633,   686,   741,   800,   861,   926,   993,   1064,  1139,  1216,  1297, 
            1382,  1470,  1562,  1658,  1757,  1861,  1968,  2079,  2195,  2314,  2438,  2567,  2700,  2837,  2979,  3125
        },
    },
    {
        {
            1,     1,     2,     5,     10,    18,    31,    48,    72,    101,   139,   184,   239,   303,   378,   465,  
            564,   677,   803,   944,   1101,  1274,  1465,  1674,  1902,  2150,  2418,  2707,  3019,  3355,  3714,  4097, 
            4507,  4942,  5405,  5896,  6416,  6966,  7546,  8157,  8801,  9477,  10188, 10933, 11714, 12530, 13384, 14276,
            15207, 16177, 17188, 18240, 19334, 20471, 21652, 22877, 24148, 25464, 26828, 28240, 29700, 31210, 32770, 34382
        },
        {
            1,     1,     1,     3,     7,     13,    22,    35,    52,    74,    101,   134,   173,   220,   275,   338,  
            410,   492,   584,   687,   801,   927,   1065,  1217,  1383,  1563,  1758,  1969,  2196,  2440,  2701,  2980, 
            3277,  3594,  3931,  4288,  4666,  5066,  5488,  5932,  6401,  6893,  7409,  7951,  8519,  9113,  9734,  10383,
            11060, 11765, 12500, 13265, 14061, 14888, 15747, 16638, 17562, 18519, 19511, 20538, 21600, 22698, 23833, 25005
        },
        {
            0,     0,     1,     2,     4,     8,     14,    22,    32,    46,    63,    83,    108,   138,   172,   211,  
            256,   307,   365,   429,   500,   579,   666,   761,   864,   977,   1099,  1230,  1372,  1525,  1688,  1862, 
            2048,  2246,  2457,  2680,  2916,  3166,  3430,  3708,  4000,  4308,  4631,  4969,  5324,  5695,  6084,  6489, 
            6912,  7353,  7813,  8291,  8788,  9305,  9841,  10398, 10976, 11574, 12194, 12836, 13500, 14186, 14895, 15628
        },
        {
            0,     0,     0,     1,     2,     5,     8,     13,    19,    27,    37,    50,    65,    82,    103,   127,  
            154,   184,   219,   257,   300,   347,   399,   456,   518,   586,   659,   738,   823,   915,   1012,  1117, 
            1229,  1348,  1474,  1608,  1749,  1899,  2058,  2224,  2400,  2584,  2778,  2981,  3194,  3417,  3650,  3893, 
            4147,  4412,  4687,  4974,  5273,  5583,  5905,  6239,  6585,  6944,  7316,  7701,  8100,  8511,  8937,  9376
        },
    },
    {
        {
            1,     1,     2,     5,     11,    20,    34,    53,    78,    111,   151,   201,   260,   331,   413,   508,  
            616,   738,   876,   1030,  1201,  1390,  1598,  1826,  2075,  2345,  2638,  2954,  3294,  3660,  4051,  4470, 
            4916,  5392,  5897,  6432,  6999,  7599,  8232,  8899,  9601,  10339, 11114, 11927, 12779, 13670, 14601, 15574,
            16590, 17648, 18751, 19898, 21092, 22332, 23620, 24957, 26343, 27779, 29267, 30807, 32400, 34047, 35749, 37507
        },
        {
            1,     1,     1,     3,     6,     11,    19,    31,    45,    64,    88,    117,   152,   193,   241,   296,  
            359,   430,   511,   601,   701,   811,   932,   1065,  1210,  1368,  1538,  1723,  1921,  2135,  2363,  2607, 
            2868,  3145,  3440,  3752,  4083,  4433,  4802,  5191,  5600,  6031,  6483,  6957,  7454,  7974,  8517,  9085, 
            9677,  10295, 10938, 11607, 12303, 13027, 13778, 14558, 15366, 16204, 17072, 17971, 18900, 19861, 20854, 21879
        },
        {
            0,     0,     0,     1,     2,     5,     8,     13,    19,    27,    37,    50,    65,    82,    103,   127,  
            154,   184,   219,   257,   300,   347,   399,   456,   518,   586,   659,   738,   823,   915,   1012,  1117, 
            1229,  1348,  1474,  1608,  1749,  1899,  2058,  2224,  2400,  2584,  2778,  2981,  3194,  3417,  3650,  3893, 
            4147,  4412,  4687,  4974,  5273,  5583,  5905,  6239,  6585,  6944,  7316,  7701,  8100,  8511,  8937,  9376
        },
        {
            0,     0,     0,     0,     0,     0,     0,     0,     0,     0,     0,     0,     0,     0,     0,     0,    
            0,     0,     0,     0,     0,     0,     0,     0,     0,     0,     0,     0,     0,     0,     0,     0,    
            0,     0,     0,     0,     0,     0,     0,     0,     0,     0,     0,     0,     0,     0,     0,     0,    
            0,     0,     0,     0,     0,     0,     0,     0,     0,     0,     0,     0,     0,     0,     0,     0
        },
    } 
};


/* MC3 3-bit ADPCM (Paradigm Entertainment games).
 *
 * Layout: blocks with 32b header + 32b ch1, 32b ch2, 32b ch1...
 * Each 32b is a sub-block with 10 samples (3b x10) sharing a 'mode' of sorts.
 * More than one block is rarely used though.
 *
 * Tables and original algorithm by daemon1
 */
void decode_mpc3(VGMSTREAM* vgmstream, VGMSTREAMCHANNEL* stream, sample_t* outbuf, int channelspacing, int32_t first_sample, int32_t samples_to_do, int channel) {
    int i, sample_count = 0;

    int32_t hist = stream->adpcm_history1_32;
    int step_index = stream->adpcm_step_index;

    /* internal interleave */
    int block_samples = (vgmstream->interleave_block_size - 4) / 4 / vgmstream->channels * 10;
    first_sample = first_sample % block_samples;


    /* block header */
    if (first_sample == 0) {
        uint32_t header = read_u32le(stream->offset, stream->streamfile);
        header = (header >> channel*16);        /* lower 16=ch1, upper 16b=ch2 */
        step_index = header & 0x3f;             /* 6b */
        hist       = header & 0xffc0;           /* 16b sans 6b */
        if (hist > 0x7fff) hist -= 0x10000;     /* sign extend */
    }


    /* block samples */
    for (i = first_sample; i < first_sample + samples_to_do; i++) {
        uint32_t subblock, mode, samples, index, sign, diff;

        /* header + ch shift + sub-block number (ex. ch0 i=10: sub-block 1, ch0 i=23: sub-block 2) */
        off_t subblock_offset = stream->offset + 0x04 +  0x04 * channel + (i/10)*(4*vgmstream->channels);
        int sample_shift = (i%10)*3;

        /* expand 3b */
        subblock = read_u32le(subblock_offset, stream->streamfile);
        mode     = (subblock >> 30) & 0x3;  /* upper 2b */
        samples  = (subblock) & 0x3FFFFFFF; /* lower 3b*10 */

        index    = (samples >> sample_shift) & 3; /* lower 2b */
        sign     = (samples >> sample_shift) & 4; /* upper 1b */
        diff     = mpc3_table[mode][index][step_index];
        if (sign == 0) 
            hist += (- 1 - diff);
        else
            hist += diff;

        /* new step + clamp */
        step_index += step_table[index];
        if (step_index < 0) step_index = 0;
        else if (step_index > 63) step_index = 63;

        /* output */
        outbuf[sample_count] = hist;
        sample_count += channelspacing;
    }


    /* internal interleave: increment offset on complete frame */
    if (i == block_samples) stream->offset += vgmstream->interleave_block_size;

    stream->adpcm_history1_32 = hist;
    stream->adpcm_step_index  = step_index;
}
